New dialog to handle format options
authoroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 20 Nov 2005 21:01:57 +0000 (21:01 +0000)
committeroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 20 Nov 2005 21:01:57 +0000 (21:01 +0000)
gpsbabel/win32/gui-2/options.dfm [new file with mode: 0644]
gpsbabel/win32/gui-2/options.pas [new file with mode: 0644]

diff --git a/gpsbabel/win32/gui-2/options.dfm b/gpsbabel/win32/gui-2/options.dfm
new file mode 100644 (file)
index 0000000..70f3a3c
Binary files /dev/null and b/gpsbabel/win32/gui-2/options.dfm differ
diff --git a/gpsbabel/win32/gui-2/options.pas b/gpsbabel/win32/gui-2/options.pas
new file mode 100644 (file)
index 0000000..eeb3fdc
--- /dev/null
@@ -0,0 +1,581 @@
+unit options;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  TypInfo, gnugettext, gnugettextDx,\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls, ExtCtrls, ComCtrls, Buttons,\r
+  Common;\r
+\r
+type\r
+  TfrmOptions = class(TForm)\r
+    pnBottom: TPanel;\r
+    pnOptions: TPanel;\r
+    btnOK: TBitBtn;\r
+    btnCancel: TBitBtn;\r
+    btnHelp: TBitBtn;\r
+    mmWarning: TMemo;\r
+    procedure CheckBoxClicked(Sender: TObject);\r
+    procedure FormCreate(Sender: TObject);\r
+    procedure btnHelpClick(Sender: TObject);\r
+    procedure FormKeyDown(Sender: TObject; var Key: Word;\r
+      Shift: TShiftState);\r
+  private\r
+    { Private declarations }\r
+    FOpts: TStringList;\r
+    FCanvas: TCanvas;\r
+    FInitialOpts: string;\r
+    procedure CreateStringOption(const x, y, tag: Integer; o: POption; xmax: Integer = -1);\r
+    procedure CreateIntegerOption(const x, y, tag: Integer; o: POption; xmax: Integer = -1);\r
+    procedure CreateFileOption(const x, y, tag: Integer; o: POption; IsInput: Boolean; xmax: Integer = -1);\r
+    function FindUpDown(AControl: TControl): TUpDown;\r
+    function GetOptsStr: string;\r
+    procedure OptionOpenFile(Sender: TObject);\r
+    procedure OptionSaveFile(Sender: TObject);\r
+    function ParseOptsLine(const Line: string; List: TStrings): Integer;\r
+    procedure SetOpts(AList: TStringList);\r
+    procedure SetOptsStr(const AValue: string);\r
+  public\r
+    { Public declarations }\r
+    FFormat: string;\r
+    FIsInput: Boolean;\r
+    constructor Create(AOwner: TComponent); override;\r
+  property\r
+    Opts: TStringList read FOpts write SetOpts;\r
+    property OptsStr: string read GetOptsStr write SetOptsStr;\r
+  end;\r
+\r
+type\r
+  eUnknownOption = class(Exception);\r
+  eParserError = class(Exception);\r
+  \r
+var\r
+  frmOptions: TfrmOptions;\r
+\r
+implementation\r
+\r
+uses\r
+  utils, main;\r
+\r
+{$R *.DFM}\r
+\r
+constructor TfrmOptions.Create(AOwner: TComponent); // override;\r
+begin\r
+  inherited Create(AOwner);\r
+  TranslateComponent(Self);\r
+  FCanvas := Main.frmMain.stbMain.Canvas;\r
+  mmWarning.Lines.Add(_('Be aware, that most options are made for the output side. '));\r
+  mmWarning.Lines.Add(_('Currently we don''t have a flag which tells us which direction is used the options.'));\r
+end;\r
+\r
+procedure TfrmOptions.SetOpts(AList: TStringList);\r
+var\r
+  i, j: Integer;\r
+  c: TComponent;\r
+  wc: TControl;\r
+  o: POption;\r
+  chb: TCheckBox;\r
+  xy: TPoint;\r
+  xmax: Integer;\r
+  lb: TLabel;\r
+begin\r
+  FOpts := AList;\r
+\r
+  xy.x := 0;\r
+  xy.y := 8;\r
+  xmax := 0;\r
+\r
+  for i := 0 to FOpts.Count - 1 do\r
+  begin\r
+    o := Pointer(FOpts.Objects[i]);\r
+    o.chb := nil;\r
+    o.edit := nil;\r
+\r
+    if (FFormat = '') then\r
+    begin\r
+      FFormat := o.format;\r
+      btnHelp.Hint := 'http://www.gpsbabel.org/readme.html#' + FFormat;\r
+      btnHelp.ShowHint := True;\r
+    end;\r
+\r
+    if FIsInput and (\r
+       (AnsiPos('generate ', o.hint) <> 0) or\r
+       (AnsiPos(' generate', o.hint) <> 0) or\r
+       (AnsiPos('output ', o.hint) <> 0) or\r
+       (AnsiPos(' output', o.hint) <> 0) or\r
+       (AnsiPos('write', o.hint) <> 0) or\r
+       (AnsiPos(' write', o.hint) <> 0)) then Continue;\r
+\r
+    chb := TCheckBox.Create(nil);\r
+    o.chb := chb;\r
+    chb.Name := '___' + o.name;\r
+    chb.OnClick := CheckBoxClicked;\r
+    chb.Tag := i + 1;\r
+\r
+    InsertComponent(chb);\r
+\r
+    chb.ParentFont := False;\r
+    chb.Font := Main.frmMain.stbMain.Font;\r
+    chb.Left := 8;\r
+    chb.Top := xy.y;\r
+    chb.Caption := dgettext('Options', o.Hint);\r
+    chb.Alignment := taRightJustify;\r
+    chb.Checked := False;\r
+    chb.Parent := pnOptions;\r
+\r
+    chb.Hint := SysUtils.Format(_('Short "%s"'), [o.name]);\r
+    chb.ShowHint := True;\r
+    chb.Width := 21 + Trunc(FCanvas.TextWidth(chb.Caption) * 1.25);\r
+\r
+    xy.y := xy.y + chb.Height + 8;\r
+    if (o.otype <> 4) then\r
+      if (chb.Width > xy.x) then xy.x := chb.Width;\r
+    if (chb.Width > xy.x) then\r
+      xmax := chb.Width;\r
+  end;\r
+\r
+  xy.y := 8;\r
+  xy.X := xy.X + 8;\r
+  if (xy.X < 42) then xy.X := 42;\r
+\r
+  for i := 0 to FOpts.Count - 1 do\r
+  begin\r
+    o := Pointer(FOpts.Objects[i]);\r
+    o.edit := nil;\r
+    \r
+    if (o.chb = nil) then Continue;\r
+\r
+    // ('unknown', 'integer', 'float', 'string', 'boolean', 'file', 'outfile');\r
+    case o.otype of\r
+      1: CreateIntegerOption(xy.X, xy.Y - 2, i + 1, o, xmax);\r
+      2, 3: CreateStringOption(xy.X, xy.Y - 2, i + 1, o, xmax);\r
+      4: ;\r
+      5: if FIsInput then CreateFileOption(xy.X, xy.Y - 2, i + 1, o, True, xmax);\r
+      6: if not FIsInput then CreateFileOption(xy.X, xy.Y - 2, i + 1, o, False, xmax);\r
+    end;\r
+    if (o.edit <> nil) then\r
+      o.edit.Enabled := False;\r
+    xy.y := xy.y + chb.Height + 8;\r
+  end;\r
+\r
+  xy.X := 0;\r
+  xy.Y := 0;\r
+\r
+  for i := 0 to ComponentCount - 1 do\r
+  begin\r
+    c := Components[i];\r
+    if not c.InheritsFrom(TControl) then Continue;\r
+    if (c is TPanel) then Continue;\r
+    wc := Pointer(c);\r
+    if (wc.Parent <> pnOptions) then Continue;\r
+\r
+    j := wc.Left + wc.Width;\r
+    if (j > xy.X) then xy.X := j;\r
+    j := wc.Top + wc.Height;\r
+    if (j > xy.Y) then xy.Y := j;\r
+    if ( wc.Name = '' ) then Continue;\r
+  end;\r
+\r
+  Self.Width := xy.X + 8 + (Self.Width - Self.ClientWidth);\r
+  Self.Height := xy.Y + 8 +\r
+    mmWarning.Height + + pnBottom.Height +\r
+    (Self.Height - Self.ClientHeight);\r
+\r
+  i := btnCancel.Left - btnOK.Left;\r
+  btnCancel.Left := pnBottom.Width - btnCancel.Width - btnHelp.Left;\r
+  btnOK.Left := btnCancel.Left - i;\r
+end;\r
+\r
+function TfrmOptions.GetOptsStr: string;\r
+var\r
+  i: Integer;\r
+  o: POption;\r
+  c: TComponent;\r
+  s: string;\r
+begin\r
+  Result := '';\r
+  for i := 0 to FOpts.Count - 1 do\r
+  begin\r
+    o := Pointer(FOpts.Objects[i]);\r
+    if (o.chb = nil) or not(o.chb.Checked) then Continue;\r
+    if (Result <> '') then\r
+      Result := Result + ',';\r
+    Result := Result + o.name;\r
+    if (o.edit = nil) then Continue;\r
+    s := GetStrProp(o.edit, 'Text');\r
+    if (Pos(' ', s) <> 0) or (Pos('"', s) <> 0) or (Pos(',', s) <> 0) then\r
+      s := SysUtils.AnsiQuotedStr(s, '"');\r
+    Result := SysUtils.Format('%s=%s', [Result, s]);\r
+  end;\r
+end;\r
+\r
+procedure TfrmOptions.SetOptsStr(const AValue: string);\r
+var\r
+  l: TStrings;\r
+  i, j: Integer;\r
+  s, name, value: string;\r
+  o: POption;\r
+  ud: TUpDown;\r
+begin\r
+  l := TStringList.Create;\r
+  try\r
+\r
+    try\r
+      ParseOptsLine(AValue, l);\r
+    except\r
+      on E: exception do\r
+        raise eParserError.Create(_('Invalid line format!'));\r
+    end;\r
+\r
+    for i := 0 to l.Count - 1 do\r
+    begin\r
+      s := l.Strings[i];\r
+      j := Pos('=', s);\r
+      if (j > 0) then\r
+      begin\r
+        name := Copy(s, 1, j - 1);\r
+        value := Copy(s, j + 1, Length(s) - j);\r
+      end\r
+        else\r
+      begin\r
+        Name := s;\r
+        Value := '';\r
+      end;\r
+      if (name = '') then Continue;\r
+\r
+      j := FOpts.IndexOf(name);\r
+      if (j < 0) then\r
+        raise eUnknownOption.CreateFmt(_('Unknown option "%s"!'), [name]);\r
+\r
+      o := Pointer(FOpts.Objects[j]);\r
+      if (o.edit <> nil) then\r
+      begin\r
+        o.chb.Checked := True;\r
+        ud := FindUpDown(o.Edit);\r
+        if (ud <> nil) then\r
+          ud.Position := StrToInt(Value)\r
+        else\r
+          SetStrProp(o.edit, 'Text', Value);\r
+      end\r
+      else if (o.otype = 4) then\r
+        o.chb.Checked := (value = '') or (value <> '0');\r
+    end;\r
+  finally\r
+    l.Free;\r
+  end;\r
+  FInitialOpts := GetOptsStr;\r
+end;\r
+\r
+procedure TfrmOptions.CheckBoxClicked(Sender: TObject);\r
+var\r
+  i: Integer;\r
+  c: TComponent;\r
+  chb: TCheckBox;\r
+  ctrl: TWinControl;\r
+begin\r
+  if (Sender = nil) or not (Sender is TCheckBox) then Exit;\r
+  chb := Pointer(Sender);\r
+\r
+  for i := 0 to ComponentCount - 1 do\r
+  begin\r
+    c := Components[i];\r
+    if (c = chb) or not(c.InheritsFrom(TWinControl)) then Continue;\r
+    if (c.Tag <> chb.Tag) then Continue;\r
+    ctrl := Pointer(c);\r
+    ctrl.Enabled := chb.Checked;\r
+  end;\r
+end;\r
+\r
+procedure TfrmOptions.CreateStringOption(const x, y, tag: Integer; o: POption; xmax: Integer);\r
+var\r
+  ed: TEdit;\r
+begin\r
+  ed := TEdit.Create(Self);\r
+  o.edit := ed;\r
+\r
+  ed.Left := x;\r
+  ed.Top := y;\r
+  ed.Tag := tag;\r
+  ed.Parent := pnOptions;\r
+\r
+  if (o.def <> nil) then\r
+    ed.Text := string(o.def);\r
+end;\r
+\r
+procedure TfrmOptions.CreateIntegerOption(const x, y, tag: Integer; o: POption; xmax: Integer);\r
+var\r
+  ed: TEdit;\r
+  cb: TComboBox;\r
+  up: TUpDown;\r
+  i:  Integer;\r
+begin\r
+  if (o.min <> nil) and (o.max <> nil) and\r
+     ((StrToInt(o.max) - StrToInt(o.min)) < 32) then\r
+  begin\r
+    cb := TComboBox.Create(Self);\r
+    o.edit := cb;\r
+    cb.Left := x;\r
+    cb.Top := y;\r
+    cb.Tag := tag;\r
+    if (cb.Left + cb.Width < xmax) then\r
+      cb.Left := xmax - cb.Width;\r
+    cb.Parent := pnOptions;\r
+\r
+    for i := StrToInt(o.min) to StrToInt(o.max) do\r
+      cb.Items.Add(IntToStr(i));\r
+    if (o.def <> nil) then\r
+      cb.Text := o.def\r
+    else\r
+      cb.ItemIndex := 0;\r
+    Exit;\r
+  end;\r
+\r
+  ed := TEdit.Create(Self);\r
+  o.edit := ed;\r
+\r
+  ed.Left := x;\r
+  ed.Top := y;\r
+  ed.Tag := tag;\r
+  ed.Parent := pnOptions;\r
+\r
+  up := TUpDown.Create(Self);\r
+  up.Parent := pnOptions;\r
+\r
+  ed.Width := ed.Width - up.Width;\r
+  up.Left := ed.Left + ed.Width;\r
+  up.Top := ed.Top;\r
+  if (o.min <> nil) then\r
+    up.Min := StrToInt(o.min)\r
+  else\r
+    up.Min := -(MAXSHORT-1);\r
+  if (o.max <> nil) then\r
+    up.Max := StrToInt(o.max)\r
+  else\r
+    up.Max := MAXSHORT;\r
+  if (o.def <> nil) then\r
+    up.Position := StrToInt(o.def);\r
+  up.Associate := ed;\r
+end;\r
+\r
+procedure TfrmOptions.FormCreate(Sender: TObject);\r
+begin\r
+  TranslateComponent(Self);\r
+end;\r
+\r
+procedure TfrmOptions.btnHelpClick(Sender: TObject);\r
+begin\r
+  WinOpenFile('http://www.gpsbabel.org/readme.html#' + FFormat);\r
+end;\r
+\r
+procedure TfrmOptions.CreateFileOption(const x, y, tag: Integer; o: POption; IsInput: Boolean; xmax: Integer = -1);\r
+var\r
+  ed: TEdit;\r
+  btn: TSpeedButton;\r
+begin\r
+  ed := TEdit.Create(Self);\r
+  o.edit := ed;\r
+\r
+  ed.Left := x;\r
+  ed.Top := y;\r
+  ed.Tag := tag;\r
+  ed.Parent := pnOptions;\r
+\r
+  btn := TSpeedButton.Create(Self);\r
+  btn.Parent := pnOptions;\r
+  btn.Tag := tag;\r
+  ed.Width := ed.Width - btn.Width;\r
+  btn.Left := ed.Left + ed.Width;\r
+  btn.Top := ed.top;\r
+\r
+  if IsInput then\r
+  begin\r
+    btn.OnClick := Self.OptionOpenFile;\r
+    frmMain.ImageList1.GetBitmap(15, btn.Glyph);\r
+  end\r
+    else\r
+  begin\r
+    btn.OnClick := Self.OptionSaveFile;\r
+    frmMain.ImageList1.GetBitmap(17, btn.Glyph);\r
+  end;\r
+end;\r
+\r
+procedure TfrmOptions.OptionOpenFile(Sender: TObject);\r
+var\r
+  c: TControl;\r
+  i: Integer;\r
+  o: POption;\r
+  d: TOpenDialog;\r
+begin\r
+  if (Sender = nil) or not(Sender is TControl) then Exit;\r
+\r
+  c := Pointer(Sender);\r
+\r
+  for i := 0 to FOpts.Count - 1 do\r
+  begin\r
+    o := Pointer(FOpts.Objects[i]);\r
+    if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue;\r
+\r
+    d := TOpenDialog.Create(Self);\r
+    try\r
+      d.FileName := GetStrProp(o.edit, 'Text');\r
+      if d.Execute then\r
+        SetStrProp(o.edit, 'Text', d.FileName);\r
+    finally\r
+      d.Free;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TfrmOptions.OptionSaveFile(Sender: TObject);\r
+var\r
+  c: TControl;\r
+  i: Integer;\r
+  o: POption;\r
+  d: TSaveDialog;\r
+begin\r
+  if (Sender = nil) or not(Sender is TControl) then Exit;\r
+  \r
+  c := Pointer(Sender);\r
+\r
+  for i := 0 to FOpts.Count - 1 do\r
+  begin\r
+    o := Pointer(FOpts.Objects[i]);\r
+    if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue;\r
+\r
+    d := TSaveDialog.Create(Self);\r
+    try\r
+      d.FileName := GetStrProp(o.edit, 'Text');\r
+      if d.Execute then\r
+        SetStrProp(o.edit, 'Text', d.FileName);\r
+    finally\r
+      d.Free;\r
+    end;\r
+  end;\r
+end;\r
+\r
+function TfrmOptions.ParseOptsLine(const Line: string; List: TStrings): Integer;\r
+var\r
+  s, name, val: string;\r
+  cin, cend: PChar;\r
+  c1, c2: PChar;\r
+  ins: Boolean;\r
+begin\r
+  List.Clear;\r
+  s := Trim(line) + ',';\r
+\r
+  cin := PChar(s);\r
+  cend := cin + StrLen(cin);\r
+\r
+  while (cin < cend) do\r
+  begin\r
+    c1 := StrScan(cin, '=');\r
+    c2 := StrScan(cin, ',');\r
+    if (c1 > c2) then c1 := nil;\r
+\r
+    if (c1 <> nil) then\r
+    begin\r
+      c1^ := #0;\r
+      name := string(cin);\r
+      val := '';\r
+\r
+      c1 := c1 + 1;\r
+      while (c1^ > #0) and (c1^ <= ' ') do c1 := c1 + 1;\r
+\r
+      if (c1^ = '"') then // dequote\r
+      begin\r
+        while (c1 < cend) do\r
+        begin\r
+          c1 := c1 + 1;\r
+          if (c1^ = '"') then\r
+          begin\r
+            if ((c1+1)^ = '"') then\r
+              c1 := c1 + 1\r
+            else\r
+              Break;\r
+          end;\r
+          val := val + c1^;\r
+        end;\r
+        c2 := StrScan(c1 + 1, ',');\r
+      end\r
+        else\r
+      begin\r
+        c2^ := #0;\r
+        val := string(c1);\r
+      end;\r
+    end\r
+      else\r
+    begin\r
+      c2^ := #0;\r
+      name := string(cin);\r
+    end;\r
+\r
+    if (name <> '') then\r
+    begin\r
+      if (val <> '') then\r
+        list.Add(Format('%s=%s', [name, val]))\r
+      else\r
+        list.Add(name);\r
+    end;\r
+\r
+    if (c2 = nil) then\r
+      Break\r
+    else\r
+      cin := c2 + 1;\r
+  end;\r
+\r
+  Result := List.Count;\r
+end;\r
+\r
+function TfrmOptions.FindUpDown(AControl: TControl): TUpDown;\r
+var\r
+  i: Integer;\r
+  c: TComponent;\r
+begin\r
+  Result := nil;\r
+  for i := 0 to ComponentCount - 1 do\r
+  begin\r
+    c := Components[i];\r
+    if c.InheritsFrom(TUpDown) and (TUpDown(c).Associate = AControl) then\r
+    begin\r
+      Result := Pointer(c);\r
+      Exit;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TfrmOptions.FormKeyDown(Sender: TObject; var Key: Word;\r
+  Shift: TShiftState);\r
+var\r
+  str: string;\r
+begin\r
+  if (Key <> 27) then Exit;\r
+\r
+  str := GetOptsStr;\r
+  if (str <> FInitialOpts) then\r
+  begin\r
+    if not(MessageDlg(_('Discard changes?'), mtWarning, mbOKCancel, 0) = mrOK) then\r
+      Exit; \r
+  end;\r
+  ModalResult := mrCancel;\r
+end;\r
+\r
+end.\r